import moment from "moment";

/**
 * 获取当前时间
 * @param {string} format 时间格式
 * @returns {string} 当前时间
 */
const nowDate = (format: string) => {
  const date = new Date();
  const map: { [key: string]: string } = {
    yyyy: date.getFullYear().toString(),
    MM: ("0" + (date.getMonth() + 1)).slice(-2),
    dd: ("0" + date.getDate()).slice(-2),
    HH: ("0" + date.getHours()).slice(-2),
    mm: ("0" + date.getMinutes()).slice(-2),
    ss: ("0" + date.getSeconds()).slice(-2),
  };

  return format.replace(/yyyy|MM|dd|HH|mm|ss/g, (matched) => map[matched]);
};

/**
 * 时间格式转化
 * @param {string} date 时间字符串[任意]
 * @param {string} format 时间格式
 * @returns {string} 格式化后的时间
 */
const dateFormat = (date: string, format: string) => {
  return moment(date).format(format);
};

/**
 * 获取范围的时间
 * @param {string} date 时间字符串[任意] 默认为当前时间
 * @param {IDateType.DateType} type 时间范围类型 默认为day
 * @param {1|0} isStart 是否为开始时间 默认为1
 * @param {string} format 时间格式 默认为yyyy-MM-dd
 * @returns {string} 格式化后的时间
 */
const dateRange = (
  date: string = nowDate("yyyy-MM-dd"),
  type: IDateType.DateType = "day",
  isStart: 1 | 0 = 1,
  format: string = "yyyy-MM-dd"
) => {
  const start = moment(date).startOf(type).format(format);
  const end = moment(date).endOf(type).format(format);
  return isStart ? start : end;
};

/**
 * 根据key获取tree中的元素
 * @param {ITreeType.ITree[]} tree 树结构
 * @param {string | number} key 节点key
 * @param {string} value 要查询的节点的键值
 * @returns {string} key对应节点的value键的属性值
 */
const getTreeValueById = (
  tree: ITreeType.ITree[],
  key: string | number,
  value: string
): string | undefined => {
  for (const node of tree) {
    if (node.key === key) {
      return node[value as keyof ITreeType.ITree] as unknown as string;
    }
    if (node.children) {
      const result = getTreeValueById(node.children, key, value);
      if (result) {
        return result;
      }
    }
  }
  return undefined;
};

/**
 * 根据key获取tree中的节点
 * @param {ITreeType.ITree[]} tree 树结构
 * @param {string | number} key 节点key
 * @returns {ITreeType.ITree | undefined} key对应的节点【无子节点】
 */
const getTreeNodeById = (
  tree: ITreeType.ITree[],
  key: string | number
): ITreeType.ITree | undefined => {
  for (const node of tree) {
    if (node.key === key) {
      return {
        ...node,
        children: undefined,
      };
    }
    if (node.children) {
      const result = getTreeNodeById(node.children, key);
      if (result) {
        return result;
      }
    }
  }
  return undefined;
};

/**
 * 防抖函数
 */
const debounce = (fn: (...args: any[]) => void, delay: number) => {
  let timer: number | null = null;
  return function (this: any, ...args: any[]) {
    if (timer) {
      clearTimeout(timer);
    }
    timer = window.setTimeout(() => {
      fn.apply(this, args);
    }, delay);
  };
};
/**
 * 节流函数
 */
const throttle = (fn: (...args: any[]) => void, delay: number) => {
  let timer: number | null = null;
  return function (this: any, ...args: any[]) {
    if (!timer) {
      timer = window.setTimeout(() => {
        fn.apply(this, args);
        timer = null;
      }, delay);
    }
  };
};

export {
  nowDate,
  dateFormat,
  dateRange,
  getTreeValueById,
  getTreeNodeById,
  debounce,
  throttle,
};
